<?php

namespace App\Repositories;

use App\Models\Bonus;
use App\Models\Cart;
use App\Models\Config;
use App\Models\Goods;
use App\Models\GoodsAttribute;
use App\Models\IntegralLog;
use App\Models\Order;
use App\Models\OrderGoods;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use InfyOm\Generator\Common\BaseRepository;

/**
 * Class OrderRepository
 * @package App\Repositories
 * @version September 18, 2017, 5:48 am UTC
 *
 * @method Order findWithoutFail($id, $columns = ['*'])
 * @method Order find($id, $columns = ['*'])
 * @method Order first($columns = ['*'])
*/
class OrderRepository extends BaseRepository
{
    /**
     * @var array
     */
    protected $fieldSearchable = [
        'user_id',
        'sn',
        'status',
        'pay_type',
        'pay_status',
        'remark',
        'goods_number',
        'price',
        'acquire_integral',
        'use_integral',
        'pay_money',
        'wxpay_record_id',
        'shipping_status',
        'shipping_at',
        'will_take',
        'express_type',
        'express_sn',
        'express_info',
        'json',
        'request_params',
        'pay_at',
    ];

    /**
     * Configure the Model
     **/
    public function model()
    {
        return Order::class;
    }

    public function add(Request $request, $type=1)
    {
        $shipping_at = \request('shipping_at');
        $user = Auth::user();
        if($user->in_blacklist){
            return '您的账号安全存在异常，无法下单';
        }
        $goods_array = json_decode(request('goods','[]'), true);
        $attributes_array = json_decode(request('attributes','[]'), true);
        $data['will_take'] = \request('will_take',0);
        $data['goods_number'] = $this->getAllNumber($goods_array)+$this->getAllNumber($attributes_array);
        $data['sn'] = date('YmdHis').rand(1000,9999);
        $data['pay_type'] = $type;
        $data['remark'] = \request('remark');
        $data['shipping_at'] = \request('shipping_at');
        $data['shipping_end_at'] = \request('shipping_end_at');
        if($data['shipping_at']){
            $data['shipping_at'] = date('Y-m-d H:i:s',strtotime($data['shipping_at']));
        }else{
            $data['will_take'] = 1;
        }
        $data['shipping_status'] = 1;
        if(!$data['shipping_end_at'] && $data['shipping_at']){
            $_time_value = Config::where('type','deliver_goods_interval_time')->value('value');
            $data['shipping_end_at'] = date('Y-m-d H:i:s',strtotime($data['shipping_at'])+$_time_value*60);
        }
        $data['express_info'] = \request('express_info');
        $data['user_id'] = Auth::id();
        $data['request_params'] = json_encode($request->all(),256);
        $data['address_id'] = \request('address_id',null);
        $goods = $this->checkOrderGoods($goods_array);
        $attributes = $this->checkOrderAttributes($attributes_array);

        if(!is_array($goods) && is_string($goods)){
            return $goods;
        }
        if(!is_array($attributes) && is_string($attributes)){
            return $attributes;
        }
        //计算价格
        $price = 0;
        if($goods){
            foreach ($goods as $v) {
                if($v->sale_price>0)
                    $price += $v->sale_price * $v->_number;
                else
                    $price += $v->market_price * $v->_number;
            }
        }
        if($attributes){
            foreach ($attributes as $v) {
                if($v->sale_price>0)
                    $price += $v->sale_price * $v->_number;
                else
                    $price += $v->market_price * $v->_number;
            }
        }

        $price = sprintf("%7.2f", $price);
        if($price==0){
            return '订单价格不能为0';
        }
        //地址设置 默认
        if(isset($data['address_id'])){
            foreach ($user->addresses as $address) {
                if($address->is_select==0){
                    if($data['address_id']==$address->id){
                        $address->is_select = 1;
                        $address->save();
                    }
                }else{
                    if($data['address_id']!=$address->id){
                        $address->is_select = 0;
                        $address->save();
                    }
                }
            }
        }

        //排序商品或属性 id出错
        if($goods===false || $attributes===false){
            return '商品数量出错';
        }
        //判断优惠券存在与否
        $bonus_id = \request('bonus_id',null);
        if($bonus_id){
            $bonus = Bonus::find($bonus_id);
            if(!$bonus || $bonus->use_status)
                return '优惠券不存在';
            $bonus_money = $bonus->money;
        }else{
            $bonus_money = 0;
        }
        $data['discount_price'] = $bonus_money;
        $_use_integral = sprintf("%.0f",($price-$bonus_money)*100);
        if($type==1)
            $data['use_integral'] = $_use_integral>0?$_use_integral:0;
        else
            $data['use_integral'] = \request('use_integral',0);
        $data['acquire_integral'] = $data['use_integral'];
        //判断积分
        if($data['use_integral'] && $user->integral<$data['use_integral']){
            return '积分不够';
        }
        if($user->service_message){
            $user->service_message = null;
            $user->save();
            $data['remark'] .= '  客服留言:'.$user->service_message;
        }

        //创建订单 和订单物品
        $order = Order::create($data);
        if(isset($bonus)){
            $bonus->use_status = 1;
            $bonus->order_id = $order->id;
            $bonus->use_date = date('Y-m-d H:i:s');
            $bonus->save();
        }
        $this->addOrderAttributes($goods,$order->id,false);
        $this->addOrderAttributes($attributes, $order->id);

        //积分
        $user->integral -= $data['use_integral'];
        $user->integral = $user->integral>0?$user->integral:0;
        $user->save();

        //TODO 判断是否需要配送费
        $config_res = app()->build(ConfigRepository::class);
        $configs = $config_res->getMapByGroup('system');
        if($price<$configs['express_need_money'] && $data['will_take']!=1){
            $order->price = $price + $configs['delivery_fee'];
            $order->is_need_delivery_fee = 1;
        }else{
            $order->price = $price;
        }
        $order->calculate_price = $price;
        $order->pay_money = sprintf("%7.2f",$price - $bonus_money - $data['use_integral']/100);
        $order->calculate_pay_price = sprintf("%7.2f",$price - $bonus_money - $data['use_integral']/100);
        $order->calculate_goods_number = $order->goods_number;
        $order->save();
        return $order;
    }

    public function getAllNumber($goods_array)
    {
        $num = 0;
        foreach ($goods_array as $item) {
            $num += $item;
        }
        return $num;
    }

    public function checkOrderGoods($goods_array)
    {
        $res = [];
        foreach ($goods_array as $k=>$v) {
            $goods = Goods::find($k);

            $is_sale = $this->checkSale($goods);
            if(!$is_sale)
                return $goods->name.'已经下架';
            if($goods && ($goods->number>=$v)){
                if($goods->attributesByStatus->count()==0){
                    $goods->_number = $v;
                    $res[] = $goods;
                }else
                    return '商品发生变化，请重新购买';
            }else{
                return $goods->name.'数量不足';
            }
        }
        return $res;
    }

    public function checkOrderAttributes($attributes_array)
    {
        $res = [];
        foreach ($attributes_array as $k=>$v) {
            $attribute = GoodsAttribute::find($k);

            $is_sale = $this->checkSale($attribute->goods);
            if(!$is_sale)
                return $attribute->goods->name.' '.$attribute->name.'已经下架';

            if($attribute && ($attribute->number>=$v)){
                $attribute->_number = $v;
                $res[] = $attribute;
            }else{
                return $attribute->goods->name.' '.$attribute->name.'数量不足';
            }
        }
        return $res;
    }

    public function checkSale($goods)
    {
        if(!$goods->is_on_sale)
            return false;
//        if(strtotime($goods->sale_start_date)>time())
//            return false;
//        if(strtotime($goods->sale_end_date)<time())
//            return false;
        return true;
    }

    public function addOrderAttributes($attributes,$order_id,$is_attribute=true)
    {
        foreach ($attributes as $attribute) {
            if($is_attribute){
//                Cart::where('attribute_id', $attribute->id)->where('user_id', Auth::id())->update(['number'=>0]);
                Cart::where('goods_id', $attribute->id)->where('user_id', Auth::id())->delete();
                $_attribute = [
                    'order_id'=>$order_id,
                    'goods_id'=>$attribute->goods->id,
                    'number'=>$attribute->_number,
                    'key'=>$attribute->key,
                    'price'=>$attribute->sale_price>0?$attribute->sale_price:$attribute->market_price,
                    'attribute_id'=>$attribute->id
                ];
            }else{
                Cart::where('goods_id', $attribute->id)->where('user_id', Auth::id())->delete();
                $_attribute = [
                    'order_id'=>$order_id,
                    'price'=>$attribute->sale_price>0?$attribute->sale_price:$attribute->market_price,
                    'goods_id'=>$attribute->id,
                    'number'=>$attribute->_number,
                ];
            }
            OrderGoods::create($_attribute);
        }
    }

    public function success(Order $order)
    {
        $order->pay_status = 1;
        $order->pay_at = date('Y-m-d H:i:s');
        $order->status = 2;
        //上级增加积分
        $user = $order->user;
        if($user->parent_id){
            $parent = User::find($user->parent_id);
            if($parent){
                $integral = $order->price * 2;
                $integral = sprintf("%.0f",$integral);
                $parent->integral += $integral;
                $parent->save();
                IntegralLog::create([
                    'user_id'=>$user->parent_id,
                    'type'=>1,
                    'add_type'=>1,
                    'junior_id'=>$user->id,
                    'title'=>'邀请好友奖励菜金',
                    'amount'=>$integral,
                    'calculate'=>$parent->integral,
                ]);
            }
        }
        if($order->use_integral>0){
            IntegralLog::create([
                'user_id'=>$user->id,
                'type'=>2,
                'add_type'=>0,
                'junior_id'=>0,
                'title'=>'支出积分',
                'amount'=>$order->use_integral,
                'calculate'=>$user->integral,
            ]);
        }
        //合并订单
        $this->mergeOrder($order);
        $order->save();
    }

    public function handleGoodsNum($order,$up=true,$back=true)
    {
        if($up){
            foreach ($order->goods as $v) {
                if($v->attribute_id){
                    GoodsAttribute::where('id', $v->attribute_id)->increment('sales_count', $v->number);
                    Goods::where('id', $v->goods_id)->increment('sales_count', $v->number);
                    if($back){
                        GoodsAttribute::where('id', $v->attribute_id)->decrement('number',$v->number);
                        Goods::where('id', $v->goods_id)->decrement('number',$v->number);
                    }
                }else{
                    Goods::where('id', $v->goods_id)->increment('sales_count', $v->number);
                    if($back)
                        Goods::where('id', $v->goods_id)->decrement('number',$v->number);
                }
            }
        }else{
            foreach ($order->goods as $v) {
                if($v->attribute_id){
                    GoodsAttribute::where('id', $v->attribute_id)->decrement('sales_count', $v->number);
                    Goods::where('id', $v->goods_id)->decrement('sales_count', $v->number);
                    if($back){
                        GoodsAttribute::where('id', $v->attribute_id)->increment('number',$v->number);
                        Goods::where('id', $v->goods_id)->increment('number',$v->number);
                    }
                }else{
                    Goods::where('id', $v->goods_id)->decrement('sales_count', $v->number);
                    if($back)
                        Goods::where('id', $v->goods_id)->increment('number',$v->number);
                }
            }
        }
    }

    public function error(Order $order,$status=1,$back=true)
    {
        $this->handleGoodsNum($order,false, $back);
        $bonus = $order->bonus;
        if($bonus){
            $bonus->order_id = null;
            $bonus->use_date = null;
            $bonus->use_status = 0;
            $bonus->save();
        }
//        $order->pay_status = 0;
        $order->status = $status;
        $order->save();
        $user = $order->user;
        $user->integral += $order->use_integral;
        $user->save();
    }

    public function orderCutPrice(Order $order,$price)
    {
        $kou_jifen = $price*100;
        $shenyu_jifen = $order->acquire_integral - $kou_jifen;
        if($shenyu_jifen>=0){
            $order->acquire_integral = $shenyu_jifen;
        }else{
            $order->acquire_integral = 0;
            $order->calculate_pay_price -= (-$shenyu_jifen)/100;
            $order->calculate_pay_price = $order->calculate_pay_price>0?$order->calculate_pay_price:0;
        }
        $order->calculate_price -= $price;
        $order->calculate_price = $order->calculate_price>0?$order->calculate_price:0;
        return $order;
    }

    public function mergeOrder($order)
    {
        $start_date = date('Y-m-d H:i:s',strtotime($order->shipping_at)-3600);
        $end_date = date('Y-m-d H:i:s',strtotime($order->shipping_at)+3600);
        $start_date1 = date('Y-m-d H:i:s',strtotime($order->shipping_end_at)-3600);
        $end_date1 = date('Y-m-d H:i:s',strtotime($order->shipping_end_at)+3600);
        $old_order = Order::where([
            ['is_print',0],
            ['status',2],
            ['pay_status',1],
            ['user_id',$order->user_id],
            ['user_id',$order->user_id],
            ['address_id',$order->address_id],
            ['shipping_at','>=',$start_date],
            ['shipping_at','<=',$end_date],
            ['shipping_at','>=',$start_date1],
            ['shipping_at','<=',$end_date1],
        ])->first();
        if($old_order && $old_order->id!=$order->id){
//            Bonus::where('order_id',$order->id)->update(['order_id'=>$old_order->id]);
            DB::table('order_goods')->where('order_id',$order->id)->update(['order_id'=>$old_order->id]);
            $order->merge_id = $old_order->id;
            $order->save();
            $order->delete();

            $old_order->remark .= $order->remark;
            $old_order->goods_number += $order->goods_number;
            $old_order->price += $order->price;
            $old_order->discount_price += $order->discount_price;
            $old_order->calculate_price += $order->calculate_price;
            $old_order->calculate_pay_price += $order->calculate_pay_price;
            $old_order->calculate_goods_number += $order->calculate_goods_number;
            $old_order->acquire_integral += $order->acquire_integral;
            $old_order->use_integral += $order->use_integral;
            $old_order->pay_money += $order->pay_money;
            $old_order->save();
        }
    }

    public function sendParentCaijin(Order $order)
    {
        if($order->user){
            $parent = $order->user->parent;
            if($parent){
                $wechatRepository = app()->build(WechatRepository::class);
                $integral = $order->price * 2;
                $integral = sprintf("%.0f",$integral);
                $url = 'http://mall.hellogreens.cn/web_index/?name=Redeem';
                $templateId = '-rr_UE3hO6ogTkSh9plfmQWRmnuakbtE0d6EArc1abE';
                $array = [
                    'first'=>'您好，您有新的推荐奖励到账',
                    'keyword1'=>'邀请好友奖励菜金',
                    'keyword2'=>$integral.'分',
                    'keyword3'=>date('Y-m-d H:i:s'),
                    'remark'=>"您可以点击通知查看收入详情",
                ];
                $wechatRepository->sendTempMsg($parent->openid,$templateId,$url,$array);
            }
        }
    }
}
